function [errorCode,glvar] = pco_camera_open_close(glvar)
%
%   [errorCode,glvar] = pco_camera_open_close(glvar)
%
%	* Input parameters :
%		struct     glvar
%                  reset_to_default
%	* Output parameters :
%                  errorCode
%       struct     glvar
%
%open and close the camera SDK
%
%structure glvar is used to set different modes for
%load/unload library
%open/close camera SDK
%
%glvar.do_libunload: 1 unload lib at end
%glvar.do_close:     1 close camera SDK at end
%glvar.camera_open:  open status of camera SDK
%glvar.out_ptr:      libpointer to camera SDK handle
%
%if glvar does not exist,
%the library is loaded at begin and unloaded at end
%the SDK is opened at begin and closed at end
%
%function workflow
%camera SDK is opened
%camera SDK is closed
%errorCode and if available glvar is returned
%

% Test if library is loaded
if (~libisloaded('PCO_CAM_SDK'))
    % make sure the dll and h file specified below resides in your current
    % folder
    loadlibrary('PCOCam','SC2_CamExport.h','alias','PCO_CAM_SDK');
    disp('PCO_CAM_SDK library is loaded!');
end

if((exist('glvar','var'))&& ...
        (isfield(glvar,'do_libunload'))&& ...
        (isfield(glvar,'do_close'))&& ...
        (isfield(glvar,'camera_open'))&& ...
        (isfield(glvar,'out_ptr')))
    unload=glvar.do_libunload;
    cam_open=glvar.camera_open;
    do_close=glvar.do_close;
else
    unload=1;
    cam_open=0;
    do_close=1;
end

%Declaration of variable CameraHandle
%out_ptr is the CameraHandle, which must be used in all other libcalls
ph_ptr = libpointer('voidPtrPtr');

%libcall PCO_OpenCamera
if(cam_open==0)
    [errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_OpenCamera', ph_ptr, 0);
    if(errorCode == 0)
        disp('PCO_OpenCamera done');
        cam_open=1;
        if((exist('glvar','var'))&& ...
                (isfield(glvar,'camera_open'))&& ...
                (isfield(glvar,'out_ptr')))
            glvar.camera_open=1;
            glvar.out_ptr=out_ptr;
        end
        ml_cam_type.wSize=uint16(1364);
        cam_type=libstruct('PCO_CameraType',ml_cam_type);
        [errorCode,out_ptr,cam_type] = calllib('PCO_CAM_SDK', 'PCO_GetCameraType', out_ptr,cam_type);
        if(errorCode)
            disp(['PCO_GetCameraType failed with error ',num2str(errorCode,'%08X')]);
        end
        disp(['SN:  ',num2str(double(cam_type.dwSerialNumber))]);
    else
        s=['PCO_OpenCamera failed with error ',num2str(errorCode,'%X')];
        disp(s);
        if(unload)
            unloadlibrary('PCO_CAM_SDK');
            disp('PCO_CAM_SDK unloadlibrary done');
        end
        return ;
    end
else
    if(isfield(glvar,'out_ptr'))
        out_ptr=glvar.out_ptr;
    end
end

if((do_close==1)&&(cam_open==1))
    %test camera recording state and stop camera, if camera is recording
    act_recstate = uint16(0);
    [errorCode,out_ptr,act_recstate] = calllib('PCO_CAM_SDK', 'PCO_GetRecordingState', out_ptr,act_recstate);
    if(errorCode)
        disp(['PCO_GetRecordingState failed with error ',num2str(errorCode,'%X')]);
    end
    
    if(act_recstate~=0)
        [errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 0);
        if(errorCode)
            disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);
        end
    end

    [errorCode] = calllib('PCO_CAM_SDK', 'PCO_CloseCamera', out_ptr);
    if(errorCode)
        s=['PCO_CloseCamera ',num2str(errorCode,'%08X')];
        disp(s);
    else
        disp('PCO_CloseCamera done');
        cam_open=0;
        if((exist('glvar','var'))&& ...
                (isfield(glvar,'out_ptr')))
            glvar.out_ptr=[];
        end
    end
end

if((unload==1)&&(cam_open==0))
    unloadlibrary('PCO_CAM_SDK');
    disp('PCO_CAM_SDK unloadlibrary done');
end

if((exist('glvar','var'))&& ...
        (isfield(glvar,'camera_open')))
    glvar.camera_open=cam_open;
end
end


